package response

import (
	"net/http"

	"github.com/golang-jwt/jwt/v5"
	"github.com/labstack/echo/v4"
)

// Result 响应结果
// @Description 通用 API 响应结构体
type Result struct {
	Code      int    `json:"code"`              // 响应码
	Message   string `json:"message,omitempty"` // 响应信息
	Data      any    `json:"data,omitempty"`    // 响应数据
	RequestId string `json:"requestId"`         // 唯一请求ID
}

// NewResult 创建响应结果
//
// 参数
//
//	-code: 响应码
//	-message: 响应信息
//	-data: 响应数据
//
// 返回
//
//	-*Result: 响应结果
func NewResult(code int, message string, data any) *Result {
	return &Result{
		Code:    code,
		Message: message,
		Data:    data,
	}
}

// NewMsgResult 创建响应结果
//
// 参数
//
//	-code: 响应码
//	-data: 响应数据
//
// 返回
//
//	-*Result: 响应结果
func NewMsgResult(message string, data any) *Result {
	return &Result{
		Message: message,
		Data:    data,
	}
}

// NewCodeMsg 创建响应结果
//
// 参数
//
//	-code: 响应码
//	-message: 响应信息
//
// 返回
//
//	-*Result: 响应结果
func NewCodeMsg(code int, message string) *Result {
	return &Result{
		Code:    code,
		Message: message,
	}
}

func NewCodeData(code int, data any) *Result {
	return &Result{
		Code: code,
		Data: data,
	}
}

// NewMsgResultNoData 创建响应结果
//
// 参数
//
//	-code: 响应码
//	-data: 响应数据
//
// 返回
//
//	-Result: 响应结果
func NewMsgResultNoData(message string, data any) *Result {
	return &Result{
		Message: message,
		Data:    data,
	}
}

// NewMsgResultNoMsg 创建响应结果(无message，只有code与data)
//
// 参数
//
//	-code: 响应码
//	-data: 响应数据
//
// 返回
//
//	-*Result: 响应结果
func NewMsgResultNoMsg(code int, data any) *Result {
	return &Result{
		Code: code,
		Data: data,
	}
}

// NewRespNoMsg 创建echo响应结果
//
// 参数
//
//	-e: echo上下文
//	-message: 响应信息
//	-data: 响应数据
func NewRespNoMsg(e echo.Context, code int, data any) {
	SetCharset(e, "")
	respResult := NewMsgResultNoMsg(code, data)
	respResult.RequestId = e.Request().Context().Value("request_id").(string)
	e.JSON(http.StatusOK, respResult)
}

// NewResponse 创建echo响应结果
//
// 参数
//
//	-e: echo上下文
//	-code: 响应码
//	-message: 响应信息
//	-data: 响应数据
func NewResponse(e echo.Context, code int, msg string, data any) {
	SetCharset(e, "")
	respResult := NewResult(code, msg, data)
	respResult.RequestId = e.Request().Context().Value("request_id").(string)
	e.JSON(http.StatusOK, respResult)
}

// NewRespCodeMsg 创建echo响应结果
//
// 参数
//
//	-e: echo上下文
//	-code: 响应码
//	-msg: 响应信息
func NewRespCodeMsg(e echo.Context, code int, msg string) {
	SetCharset(e, "")
	respResult := NewMsgResultNoMsg(code, msg)
	respResult.RequestId = e.Request().Context().Value("request_id").(string)
	e.JSON(http.StatusOK, respResult)
}

// NewRespCodeErr 创建echo响应结果
//
// 参数
//
//	-e: echo上下文
//	-code: 响应码
//	-err: 错误信息
func NewRespCodeErr(e echo.Context, code int, err error) {
	SetCharset(e, "")
	respResult := NewCodeMsg(code, err.Error())
	respResult.RequestId = e.Request().Context().Value("request_id").(string)
	e.JSON(http.StatusOK, respResult)
}

func NewRespCodeData(e echo.Context, code int, data any) {
	SetCharset(e, "")
	respResult := NewCodeData(code, data)
	respResult.RequestId = e.Request().Context().Value("request_id").(string)
	e.JSON(http.StatusOK, respResult)
}

// PageData 分页数据结构体
// @Description 通用 API 分页响应结构体
type PageData[T any] struct {
	Content []T   `json:"content"`        // 数据集合
	Records int64 `json:"records,string"` // 总条数(返回字符串)
	Pages   int64 `json:"pages,string"`   // 总页数(返回字符串)
}

// NewPageData 创建分页数据结构体
//
// 参数
//
//	-data: 分页数据
//	-records: 总记录
//	-pages: 总条数
//
// 返回
//
//	-PageData: 分页响应
func NewPageData[T any](data []T, records, pages int64) PageData[T] {
	return PageData[T]{
		Content: data,
		Records: records,
		Pages:   pages,
	}
}

// SetCharset 设置返回json字符集，默认UTF-8
func SetCharset(e echo.Context, charset string) {
	if charset == "" {
		charset = "application/json;charset=UTF-8"
	}
	e.Response().Header().Set("Content-Type", charset)
}

type LoginResult struct {
	Code    int    `json:"code"`            // 响应码
	Message string `json:"msg,omitempty"`   // 响应信息
	Token   string `json:"token,omitempty"` // 响应凭证
}

func NewLoginResult(e echo.Context, code int, msg string, token string) {
	SetCharset(e, "")
	e.JSON(http.StatusOK, &LoginResult{
		Code:    code,
		Message: msg,
		Token:   token,
	})
}

type UserInfo struct {
	User        any      `json:"user,omitempty"`
	Roles       []string `json:"roles,omitempty"`
	Permissions []string `json:"permissions,omitempty"`
}

func NewLoginInfoResult[T any](e echo.Context, data T) {
	SetCharset(e, "")
	e.JSON(http.StatusOK, data)
}

// MyClaims 自定义jwt的token返回字段
type MyClaims struct {
	UserId               int64  `json:"userId"`
	Username             string `json:"username"`
	Uuid                 string `json:"uuid"`
	jwt.RegisteredClaims        //jwt的Claims
}

// ChunkUploadResp 分片上传返回
type ChunkUploadResp struct {
	UploadId  string `json:"uploadId"`
	UploadMD5 string `json:"uploadMD5"`
	FileSize  string `json:"fileSize"`
}
